using System.Collections;
using System.Collections.Generic;
using Newtonsoft.Json;
using Sirenix.OdinInspector;
using UnityEngine;

public class VLifeCore_GirlTestCase : VLifeCore
{
    public VActBehaviour actBehaviour;

    public string DoingAction;
    public string LastAction;
    public Dictionary<string, TriggerObserver> actions;
    public void Start()
    {
        actBehaviour = gameObject.UniqueComponent<VActBehaviour>();
        actions = new Dictionary<string, TriggerObserver>();
        var mvm = GetComponent<VActProcessor>().mechine;

        actions["onInteract"] = new TriggerObserver()
        {
            start = () =>
            {
                var jsonpack = textJson;
                var processor = actBehaviour.processor;
                processor.Trigger(jsonpack.motion);
                //actBehaviour.emotionController.Show(jsonpack.emotion);
                var ttstext = jsonpack.text.ReplaceChinesePunctuation();
                //processor.Speak(ttstext,0.2f);
            }
        };

    }
    public string curInteractPose;
    public LLMIP_TestCase_GirlTextInteract.TextJsonPack textJson;
    public LLMIP_TestCase_GirlBodyInteract.JsonPack bodyJson;
    private LLMIP_TestCase_GirlTextInteract curTextHandler;
    private LLMIP_TestCase_GirlBodyInteract curBodyHandler;
    public string context;
    [Button]
    public void UserTalk()
    {
        curTextHandler = new LLMIP_TestCase_GirlTextInteract() { interactContext = "本次交互输入：" + context };
        curTextHandler.onResponse = (str) =>
        {
            curTextHandler.TryDeJson(out textJson);
            actions["onInteract"].Subscribe();
        };
        curTextHandler.Generate();
    }

    public void TouchBody()
    {
        curBodyHandler = new LLMIP_TestCase_GirlBodyInteract() { interactContext = "本次触摸肢体:" + curInteractPose };
        curBodyHandler.onResponse = (str) =>
        {
            curBodyHandler.TryDeJson(out bodyJson);
            actions["onTouch"].Subscribe();
            Save(curBodyHandler);
        };
        curBodyHandler.Generate(); //所有在回调中要自引用的代码都不能无脑放构建函数中
    }
}

public class LLMIP_TestCase_GirlTextInteract : LLMInteractPairsBase
{
    public override string prompt =>
        "你将角色扮演一位调皮可爱的女孩子，你会按照用户的输入做出回复，你的回复需要遵循如下规范:{" +
        "1.行为只能从给定的集合中选一个回复;" +
        "2.做出的动作反馈需要贴合语境和你的回复;" +
        "3.大方表达你的喜怒哀乐而不必拘泥于总是表达正向情绪;" +
        "4.更容易表达厌恶和无聊的情绪} " +
        $"行为集：{motions.ToLLMString()}，表情:{emotion.ToLLMString()}"
        ;

    private static List<string> motions = new(){ 
        "比Love_可爱","比OK_可爱",
    };
    private static List<string> emotion = new(){
        "Happy","Anger","Sad","Boring"
    };

    public override IJsonable JsonableObject => new TextJsonPack();
    public class JsonPack : IJsonable
    {
        [JsonProperty] public List<string> paramList;
        public override IJsonable CreateSample()
        {
            paramList = new(){
                "motion"+motions.ToLLMString(),
                "emotion"+emotion.ToLLMString(),
            };
            return this;
        }
    }
    public class TextJsonPack : IJsonable
    {
        public string motion;
        public string text;
        public string emotion;
    }
}

public class LLMIP_TestCase_GirlBodyInteract : LLMInteractPairsBase
{
    public override string prompt =>
        "你将角色扮演一位调皮可爱的女孩子，用户将用肢体语言和你交互，你的回复需要遵循如下规范:{" +
        "1.行为只能从给定的集合中选一个回复;}";
    public override string positiveSample => "你需要用具体的行为替换提原来的motion，audio等,正确的Json格式参考:paramList:[moition1,audio1,effect1],并返回你的内心活动";

    private static List<string> motions = new(){
        // "四处张望_女","大笑","并脚挥手可爱说Hi_可爱_女"
        "大笑","并脚挥手可爱说Hi_可爱_女"
    };
    private static List<string> audios = new(){
        "突然摸我干什么！","客人，这样是不礼貌的！","怎么了客人，有心事吗"
    };
    private static List<string> effects = new(){
        "尴尬","调皮","开心"
    };

    public override IJsonable JsonableObject => new JsonPack();
    public class JsonPack : IJsonable
    {
        [JsonProperty] public List<string> paramList;
        public override IJsonable CreateSample()
        {
            paramList = new(){
                "motion"+motions.ToLLMString(),
                "audios"+audios.ToLLMString(),
                "effects"+effects.ToLLMString(),
            };
            return this;
        }
    }

}
